<?php
/**
 *      [Discuz!] (C)2001-2099 Comsenz Inc.
 *      This is NOT a freeware, use is subject to license terms
 *
 *      $Id: dzf_base_view.php 4159 2014-09-09 03:01:36Z laoguozhang $
 */

if(!defined('IN_DISCUZ')) {
	exit('Access Denied');
}

class dzf_base_view extends dzf_base_class {	
	protected $app = null;
	protected $_data = array();
	protected $_path = './view';
	protected $ext_name = '.phtml';
	static $in_mobile = null;
	
	protected $subtemplates = array();
	protected $replacecode = array('search' => array(), 'replace' => array());
	protected $language = array();
	protected $file = '';
	
	
	public function __construct() {
		$this->app = DZF::app();
		
		if(!isset($in_mobile)) {
			if($this->app->request->getMobile() && realpath($this->_path.'/mobile')) {
				self::$in_mobile = true;
			}
		}
	}
	
	public function render($view, $data = array(), $return = false) {
		$this->app->request->getAjax() && ($view == 'common/header' || $view == 'common/footer') && $view = $view.'_ajax';
		
		$tplfile = $this->_path.'/'.$view.$this->ext_name;
		if(self::$in_mobile) {
			$mobiletplfile = $this->_path.'/mobile/'.$view.$this->ext_name;
			if(!file_exists($mobiletplfile.$this->ext_name) && !file_exists($mobiletplfile.'.php')) {
				throw new Exception('Mobile view '.$view.' is not exists.');
			}
			$tplfile = $mobiletplfile;
		} 
		extract(array_merge($this->_data, $data));

		$cachefile = './data/template/'.DZF::$appname.'_'.str_replace('/', '_', $view).'.tpl.php';
		$this->checktplrefresh($tplfile, $cachefile, $view);
		if($return) {
			return $cachefile;
		}
		
		return require ROOT_PATH.$cachefile;
	}

	public function path($path = NULL) { 
		if(isset($path)) {
			$realpath = realpath($path);
			if($realpath) {
				$this->_path = $realpath;
			}
		} else {
			return $this->_path;
		}
		return $this;
	}

	public function assign($name, $value = NULL) {
		$this->_data[$name] = $value;
	}

	public function sub($name) {
		if(!empty($name)) {
			return $this->_path.'/'.$name.'.'.$this->ext_name;
		} else {
			return false;
		}
	}
	
	public function checktplrefresh($tplfile, $cachefile, $file) {
		$timecompare = @filemtime(ROOT_PATH.$cachefile);
		if(empty($timecompare) || @filemtime($tplfile) > $timecompare) {
			$this->parse_template($tplfile, $file, $cachefile);
			return TRUE;
		}
		return FALSE;
	}
	
	public function getphptemplate($content) {
		$pos = strpos($content, "\n");
		return $pos !== false ? substr($content, $pos + 1) : $content;
	}
	
	public function parse_template($tplfile, $file, $cachefile) {
		$basefile = basename($tplfile, $this->ext_name);
		if($fp = @fopen($tplfile, 'r')) {
			$template = @fread($fp, filesize($tplfile));
			fclose($fp);
		} elseif($fp = @fopen($filename = substr($tplfile, 0, -strlen($this->ext_name)).'.php', 'r')) {
			$template = $this->getphptemplate(@fread($fp, filesize($filename)));
			fclose($fp);
		} else {
			throw new Exception('Template '.$tplfile.' is not exists.');
		}
		
		$var_regexp = "((\\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(\-\>)?[a-zA-Z0-9_\x7f-\xff]*)(\[[a-zA-Z0-9_\-\.\"\'\[\]\$\x7f-\xff]+\])*)";
		$const_regexp = "([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)";
	
		$headerexists = preg_match("/{(sub)?template\s+[\w:\/]+?header\}/", $template);
		$this->subtemplates = array();
		for($i = 1; $i <= 3; $i++) {
			if(!strpos($template, '{subtemplate') === FALSE) {
				$template = preg_replace("/[\n\r\t]*(\<\!\-\-)?\{subtemplate\s+([a-z0-9_:\/]+)\}(\-\-\>)?[\n\r\t]*/ies", "\$this->loadsubtemplate('\\2')", $template);
			}
		}
		
		$template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);
		$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
		//$template = preg_replace("/\{lang\s+(.+?)\}/ies", "\$this->languagevar('\\1')", $template);
		$template = preg_replace("/[\n\r\t]*\{date\((.+?)\)\}[\n\r\t]*/ie", "\$this->datetags('\\1')", $template);
		$template = preg_replace("/[\n\r\t]*\{eval\}\s*(\<\!\-\-)*(.+?)(\-\-\>)*\s*\{\/eval\}[\n\r\t]*/ies", "\$this->evaltags('\\2')", $template);
		$template = preg_replace("/[\n\r\t]*\{eval\s+(.+?)\s*\}[\n\r\t]*/ies", "\$this->evaltags('\\1')", $template);
		$template = str_replace("{LF}", "<?=\"\\n\"?>", $template);
		
		$template = preg_replace("/\{(\\\$[a-zA-Z0-9_\-\>\[\]\'\"\$\.\x7f-\xff]+)\}/s", "<?=\\1?>", $template);
		$template = preg_replace("/$var_regexp/es", "\$this->addquote('<?=\\1?>')", $template);
		$template = preg_replace("/\<\?\=\<\?\=$var_regexp\?\>\?\>/es", "\$this->addquote('<?=\\1?>')", $template);
		
		
		
		$headeradd = '';
		if(!empty($this->subtemplates)) {
			$headeradd .= "\n0\n";
			foreach($this->subtemplates as $fname) {
				$headeradd .= "|| \$this->checktplrefresh('$tplfile', '$cachefile', '$file')\n";
			}
			$headeradd .= ';'; 
		}
	
		$template = "<? if(!defined('IN_DISCUZ')) exit('Access Denied'); {$headeradd}?>\n$template";
	
		$template = preg_replace("/[\n\r\t]*\{template\s+([a-z0-9_:\/]+)\}[\n\r\t]*/ies", "\$this->stripvtags('<? \$this->render(\'\\1\'); ?>')", $template);
		$template = preg_replace("/[\n\r\t]*\{template\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtags('<? \$this->render(\'\\1\'); ?>')", $template);
		$template = preg_replace("/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtags('<? echo \\1; ?>')", $template);
	
		$template = preg_replace("/([\n\r\t]*)\{if\s+(.+?)\}([\n\r\t]*)/ies", "\$this->stripvtags('\\1<? if(\\2) { ?>\\3')", $template);
		$template = preg_replace("/([\n\r\t]*)\{elseif\s+(.+?)\}([\n\r\t]*)/ies", "\$this->stripvtags('\\1<? } elseif(\\2) { ?>\\3')", $template);
		$template = preg_replace("/\{else\}/i", "<? } else { ?>", $template);
		$template = preg_replace("/\{\/if\}/i", "<? } ?>", $template);
	
		$template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\}[\n\r\t]*/ies", "\$this->stripvtags('<? if(is_array(\\1)) foreach(\\1 as \\2) { ?>')", $template);
		$template = preg_replace("/[\n\r\t]*\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}[\n\r\t]*/ies", "\$this->stripvtags('<? if(is_array(\\1)) foreach(\\1 as \\2 => \\3) { ?>')", $template);
		$template = preg_replace("/\{\/loop\}/i", "<? } ?>", $template);
	
		$template = preg_replace("/\{$const_regexp\}/s", "<?=\\1?>", $template);
		if(!empty($this->replacecode)) {
			$template = str_replace($this->replacecode['search'], $this->replacecode['replace'], $template);
		}
		$template = preg_replace("/ \?\>[\n\r]*\<\? /s", " ", $template);
	
		if(!@$fp = fopen(ROOT_PATH.$cachefile, 'w')) {
			throw new Exception('directory_notfound' .dirname(ROOT_PATH.$cachefile));
		}
	
		$template = preg_replace("/\"(http)?[\w\.\/:]+\?[^\"]+?&[^\"]+?\"/e", "\$this->transamp('\\0')", $template);
		$template = preg_replace("/\<script[^\>]*?src=\"(.+?)\"(.*?)\>\s*\<\/script\>/ies", "\$this->stripscriptamp('\\1', '\\2')", $template);
		$template = preg_replace("/\<\?(\s{1})/is", "<?php\\1", $template);
		$template = preg_replace("/\<\?\=(.+?)\?\>/is", "<?php echo \\1;?>", $template);
	
		flock($fp, 2);
		fwrite($fp, $template);
		fclose($fp);
	}
	
	protected function addquote($var) {
		return str_replace("\\\"", "\"", preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s", "['\\1']", $var));
	}
	
	protected function stripvtags($expr, $statement = '') {
		$expr = str_replace("\\\"", "\"", preg_replace("/\<\?\=(\\\$.+?)\?\>/s", "\\1", $expr));
		$statement = str_replace("\\\"", "\"", $statement);
		return $expr.$statement;
	}
	
	protected function stripscriptamp($s, $extra) {
		$extra = str_replace('\\"', '"', $extra);
		$s = str_replace('&amp;', '&', $s);
		return "<script src=\"$s\" type=\"text/javascript\"$extra></script>";
	}
	
	protected function evaltags($php) {
		$php = str_replace('\"', '"', $php);
		$i = count($this->replacecode['search']);
		$this->replacecode['search'][$i] = $search = "<!--EVAL_TAG_$i-->";
		$this->replacecode['replace'][$i] = "<? $php?>";
		return $search;
	}
	
	protected function loadsubtemplate($file) {
		$tplfile = $this->render($file, array(), true);
		$filename = ROOT_PATH.$tplfile;
		if(($content = @implode('', file($filename))) || ($content = $this->getphptemplate(@implode('', file(substr($filename, 0, -4).'.php'))))) {
			$this->subtemplates[] = $tplfile;
			return $content;
		} else {
			return '<!-- '.$file.' -->';
		}
	}
}

